package com.neusoft.liduan.d0922;

public class 线程 {
	/*	程序：像QQ、微信、Eclipse都是程序
	 * 	
	 * 	进程：就是程序的实例，有端口号。程序与进程的关系就像类与对象
	 * 		至少有一个线程
	 * 	线程：是进程最小的单位
	 * 		代表程序执行的一系列操作（代码），一个CPU核心要特定时间点，只有执行一个线程
	 * 
	 * 	线程的定义(创建)
	 * 		继承java.lang.Thread
	 * 			重写run方法
	 * 		实现java.lang.Runnable
	 * 			重写run方法，但如果运行等依然需要依赖Thread类来运行
	 * 	run方法
	 * 		是线程的主体，即线程需要执行的代码都必须写在run方法中
	 * 	线程常用方法
	 * 		start()：就绪
	 * 		sleep(时间)：沉睡多久，会阻塞线程，即线程暂停，会自动唤醒
	 * 		wait(时间)：等待，会阻塞线程，即线程暂停，可以通过notify方法唤醒
	 * 		run()：注意与start()的区别，经典面试题，请问线程的启动是start()还是run()
	 * 		getName：获取线程名称
	 * 		也可以通过setName方法或Thread的构造方法设置名称
	 * 		static currentThread()：获取当前正在执行的线程
	 * 	线程的死亡：在线程代码执行完毕后，自动消亡
	 * 
	 * 	线程的同步
	 * 		1、三个无序执行的线程，放一个有序的管道中执行
	 * 		2、同步方法，即方法中所有代码都具体同步特性
	 * 		3、同步代码块，即代码块中的代码具体同步特性
	 * 			格式：synchronized(同步锁) {
			
				}
				同步锁：必须是同一个对象，同步方法的同步锁即为this
					同步代码块的同步，只要保证是同一个对象即，也可以使用this
	 * 		4、同步关键字synchronized，其它语言中比如JS，snyc
	 * 		5、同块代码支持嵌套
	 * 	同步死锁，一双筷子，两个人一人一根。
	 * 		1、2个同步锁
	 * 		2、会同步嵌套的代码
	 * 
	 * 	线程间的通信
	 * 		1、必须有同步
	 * 		2、同步锁必须是this，或者调用wait等方法的对象
	 * 		3、wait()、notify()、notifyAll()都是Object类的方法
	 * 
	 * 	1.创建两个子线程，让其中一个输出1-100之间的偶数，另一个输出1-100之间的奇数，使用两种线程的创建方式实现。

2.模拟火车站售票程序，开启三个窗口售票。(提示线程的同步)
	说明一个线程在访问变量时，读和写是分开的，有可能读了，来不及写，就被另一个线程抢去执行权
	使用Runnable和Thread继承两种方式实现
3.银行有一个账户。
有两个储户分别向同一个账户存3000元，每次存1000，存3次。每次存完打印账户余额。
问题：该程序是否有安全问题，如果有，如何解决？
【提示】
1，明确哪些代码是多线程运行代码，须写入run()方法
2，明确什么是共享数据。
3，明确多线程运行代码中哪些语句是操作共享数据的。

4.使用两个线程打印 1-100. 线程1, 线程2 交替打印

5.模拟银行取钱的问题
1.定义一个Account类
1）该Account类封装了账户编号（String）和余额（double）两个属性
2）设置相应属性的getter和setter方法
3）提供无参和有两个参数的构造器
4）系统根据账号判断与用户是否匹配，需提供hashCode()和equals()方法的重写
2.提供一个取钱的线程类
1）提供了Account类的account属性和double类的取款额的属性
2）提供带线程名的构造方法
3）run()方法中提供取钱的操作
3.在主类中创建线程进行测试。考虑线程安全问题。

6.生产者与消费者问题，附加题，经典面试题
生产者专门生产产品，当产品数达到20时候，则停止生产
消费者专门消费产品，当产品少于5的时候需要告诉生产者可以生产了。





	 */
	//main方法也是一个线程
	public static void main(String[] args) {
		t3();
	}
	
	//死锁
	public static void t4() {
		DeadLock dl = new DeadLock();
	    Thread0 t0 = new Thread0(dl);
	    Thread1 t1 = new Thread1(dl);
	    t0.start();
	    t1.start();
	}
	
	//2.模拟火车站售票程序，开启三个窗口售票。(提示线程的同步)
	public static void t3() {
//		Runnable r = new RunnableHuoChePiao();
//		Runnable r1 = new RunnableHuoChePiao();
//		Thread t1 = new Thread(r, "窗口一");
//		t1.start();
//		Thread t2 = new Thread(r, "窗口二");
//		t2.start();
//		Thread t3 = new Thread(r, "窗口三");
//		t3.start();
		ThreadHuoChePiao t1 = new ThreadHuoChePiao();
		t1.setName("窗口一");
		t1.start();
		ThreadHuoChePiao t2 = new ThreadHuoChePiao();
		t2.setName("窗口二");
		t2.start();
		ThreadHuoChePiao t3 = new ThreadHuoChePiao();
		t3.setName("窗口三");
		t3.start();
	}
	
	//1.创建两个子线程，让其中一个输出1-100之间的偶数，另一个输出1-100之间的奇数，使用两种线程的创建方式实现。
	public static void t2() {
//		ThreadFirst t1 = new ThreadFirst(0);
//		t1.setName("偶数");
//		t1.start();
//		ThreadFirst t2 = new ThreadFirst(1);
//		t2.setName("奇数");
//		t2.start();
		RunnableFirst rf = new RunnableFirst(0);
		RunnableFirst rf1 = new RunnableFirst(1);
		Thread t1 = new Thread(rf, "偶数");
		t1.start();
//		rf.setN(1);
		Thread t2 = new Thread(rf1, "奇数");
		t2.start();
	}
	
	public static void t1() {
		MyThread t = new MyThread();
		t.setName("MyThread");
		t.start();
		MyRunnable r = new MyRunnable();
		Thread t1 = new Thread(r, "MyRunnable");
		t1.start();
		System.out.println(Thread.currentThread().getName());
	}

}
